﻿using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Dispatcher;
using System.Web.Http.Controllers;
using Autofac;

namespace Freedom.Framework.Mvc.Controller
{
    public class AreaHttpControllerSelector : DefaultHttpControllerSelector
    {
        private const string AreaRouteVariableName = "area";
        private readonly IContainer _container;

        private readonly HttpConfiguration _configuration;

        public AreaHttpControllerSelector(HttpConfiguration configuration, IContainer container)
            : base(configuration)
        {
            _configuration = configuration;
            _container = container;
        }

        public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
        {
            return GetApiController(request) ?? base.SelectController(request);
        }

        private HttpControllerDescriptor GetApiController(HttpRequestMessage request)
        {
            try
            {
                var controllerName = base.GetControllerName(request);

                var areaName = GetAreaName(request);
                if (string.IsNullOrEmpty(areaName))
                {
                    return null;
                }

                var key = string.Format("{0}.WebApi.{1}Controller", areaName, controllerName).ToLower();
                var controllerDic = _container.ResolveKeyed<Dictionary<string, Type>>("ControllerDic");
                var type = controllerDic[key];

                return type == null ? null : new HttpControllerDescriptor(_configuration, controllerName, type);
            }
            catch(Exception)
            {
                return null;
            }
        }

        private static string GetAreaName(HttpRequestMessage request)
        {
            var data = request.GetRouteData();

            return !data.Values.ContainsKey(AreaRouteVariableName) ? null : data.Values[AreaRouteVariableName].ToString();
        }
    }
}
